package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.components.mq.constant.WebSocketConstants;
import com.fjwt.gz.components.mq.model.ExportExcelMQ;
import com.fjwt.gz.components.mq.vender.IMQSender;
import com.fjwt.gz.components.mq.websocket.server.PCWsChannelServer;
import com.fjwt.gz.components.oss.model.MockMultipartFile;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.components.oss.service.OssFileService;
import com.fjwt.gz.core.cache.RedisUtil;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.core.third.interfaces.IOfficialService;
import com.fjwt.gz.core.utils.SpringBeansUtil;
import com.fjwt.gz.db.bo.ActivityUserTimesBO;
import com.fjwt.gz.db.dto.*;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.*;
import com.fjwt.gz.service.activity.BaseActivityService;
import com.fjwt.gz.service.mapper.ActivityMapper;
import com.fjwt.gz.service.mapper.AwardCouponMapper;
import com.fjwt.gz.service.mapper.FansAuthMapper;
import com.fjwt.gz.service.mapper.MchInfoMapper;
import com.fjwt.gz.util.FileUtil;
import com.fjwt.gz.util.PeriodUtil;
import com.fjwt.gz.util.Utils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 营销活动信息表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class ActivityService extends ServiceImpl<ActivityMapper, ActivityEntity> {

    @Autowired
    private FansAuthMapper fansAuthMapper;
    @Autowired
    private OssRecordService ossRecordService;
    @Autowired
    private ActivityMapper activityMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private AuAuditService auAuditService;
    @Autowired
    private AuAuditFlowService auAuditFlowService;
    @Autowired
    private AuAuditRecordsService auAuditRecordsService;
    @Autowired
    private AgentInfoService agentInfoService;
    @Autowired
    private ActivitySettingService activitySettingService;
    @Autowired
    private ActivityShareService activityShareService;
    @Autowired
    private PayAuthService payAuthService;
    @Autowired
    private FansPayService fansPayService;
    @Autowired
    private FansUserService fansUserService;

    @Autowired
    private FansAgentService fansAgentService;

    @Autowired
    private AgentEmployeeService agentEmployeeService;
    @Autowired
    private FansActivityService fansActivityService;
    @Autowired
    private AgentAppService agentAppService;
    @Autowired
    private ActivityAppService activityAppService;
    @Autowired
    private PCWsChannelServer wsChannelServer;

    @Autowired
    private IOfficialService officialService;

    @Autowired
    private AwardGoodsService awardGoodsService;

    @Autowired
    private OfficialMenuService officialMenuService;

    @Autowired
    private AwardCouponMapper awardCouponMapper;

    @Autowired
    private MchInfoMapper mchInfoMapper;

    @Autowired
    private OssFileService ossFileService;

    @Autowired
    private FansService fansService;

    @Autowired
    private FansMchService fansMchService;
    @Autowired
    private AwardSettingService awardSettingService;
    @Autowired
    private AwardVirtualService awardVirtualService;
    @Autowired
    private ActivityAwardService activityAwardService;
    @Autowired
    private AwardCouponService awardCouponService;
    @Autowired
    private IMQSender mqSender;
    @Autowired
    private SysExportTaskService sysExportTaskService;
    @Autowired
    private AwardScoreService awardScoreService;
    @Autowired
    private FansAwardService fansAwardService;


    /**
     * 参与活动
     */
    public ActivityAwardVO takePartIn(FansActivityDTO fansActivityDTO) {
        if (ObjectUtils.isEmpty(fansActivityDTO.getFansId())
                || ObjectUtils.isEmpty(fansActivityDTO.getActivityId())
                || ObjectUtils.isEmpty(fansActivityDTO.getActivityTemplateNo())) {
            throw new BizException("网络故障，请稍后重试！");
        }

        BaseActivityService activityService = SpringBeansUtil.getBean(fansActivityDTO.getActivityTemplateNo() + "Service", BaseActivityService.class);
        if (ObjectUtils.isEmpty(activityService)){
            throw new BizException("网络故障，请稍后重试！");
        }
        ActivityAwardVO activityAwardVO = activityService.takePartIn(fansActivityDTO);

        fansActivityService.addFansActivityEntity(fansActivityDTO);

        return activityAwardVO;
    }


    /**
     * 活动列表--pc
     */
    public IPage<ActivityVO> queryListByPcInfo(IPage page, ActivityDTO activityDTO) {
        if (ObjectUtils.isNotEmpty(activityDTO.getAgentNo())) {
            activityDTO.setAgentNos(agentInfoService.queryAllSubAgentNo(activityDTO.getAgentNo()));
            activityDTO.setAgentNo(null);
        }
        if (ObjectUtils.isEmpty(activityDTO.getActivityTemplateNo())) {
            activityDTO.setFilterActivityTemplateNos(Arrays.asList("ACTE004", "ACTE006"));
        }
        IPage<ActivityVO> activityPage = baseMapper.queryListByPcInfo(page, activityDTO);
        if (ObjectUtils.isNotEmpty(activityPage.getRecords())) {
            for (ActivityVO record : activityPage.getRecords()) {
                if (ObjectUtils.isNotEmpty(record.getAgentNo())) {
                    List<AgentInfoEntity> agentInfoList = new ArrayList<>();
                    agentInfoService.queryAllTopAgentNo(agentInfoList, record.getAgentNo());
                    record.setAgentName(agentInfoList.stream().map(AgentInfoEntity::getAgentName).collect(Collectors.joining("/")));
                }
                if (Constants.SYS_ROLE_TYPE.MANAGER.equals(activityDTO.getSysType())
                        || (activityDTO.getSysType().equals(record.getSysType())
                        && activityDTO.getCurrentAgentNo().equals(record.getBelongInfoId()))) {
                    record.setOperable(true);
                }
            }
        }

        return activityPage;
    }

    /**
     * 绑卡消费福分数据匹配
     *
     * @param ossFileUrl
     * @return
     */
    public JSONObject cardConsumptionPoints(String ossFileUrl) {
        if (ObjectUtils.isEmpty(ObjectUtils.isEmpty(ossFileUrl))) {
            throw new BizException("请求参数异常");
        }
        JSONObject resultJson = new JSONObject();
        // 下载文件并记录oss
        File file = downloadFileAndSaveOssRecord(ossFileUrl, Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_IMPORT);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("ID", "cstmNo");
        reader.addHeaderAlias("绑卡消费次数", "num");
        reader.addHeaderAlias("福分值", "scoreValue");

        List<FansVO> read = reader.readAll(FansVO.class);
        if (ObjectUtils.isEmpty(read)) {
            throw new BizException("未查询到文件内容，请检查");
        }
        Set<String> cstmNoSet = read.stream().map(FansVO::getCstmNo).filter(ObjectUtils::isNotEmpty).collect(Collectors.toSet());
        if (ObjectUtils.isEmpty(cstmNoSet)) {
            throw new BizException("未查询到唯一标识ID，请检查");
        }

        // 筛选绑卡消费次数 >0 的数据
        read = read.stream().filter(item -> item.getNum() > 0).collect(Collectors.toList());

        List<JSONObject> successJson = new ArrayList<>();
        List<JSONObject> failJson = new ArrayList<>();

        for (FansVO fansVo : read) {
            JSONObject successResult = new JSONObject();
            JSONObject failResult = new JSONObject();
            FansVO fans = fansAuthMapper.cardConsumptionPoints(fansVo);
            // 失败信息记录
            failResult.put("ID", fansVo.getCstmNo());
            failResult.put("num", fansVo.getNum());
            failResult.put("scoreValue", fansVo.getScoreValue());
            if (ObjectUtils.isEmpty(fans)) {
                failResult.put("reason", "未进行实名认证");
                failJson.add(failResult);
                continue;
            }
            if (fans.getIsFollow().equals(1)) {
                failResult.put("reason", "未关注公众号");
                failJson.add(failResult);
                continue;
            }
            // 成功信息记录
            if (ObjectUtils.isNotEmpty(fans.getOpenId()) && ObjectUtils.isNotEmpty(fans.getPhone())) {
                successResult.put("openid", fans.getOpenId());
                successResult.put("phone", fans.getPhone());
                successResult.put("scoreValue", fansVo.getScoreValue());
                successResult.put("overDays", "60");
                successJson.add(successResult);
            }
        }

        resultJson.put("successUrl", successNormalOssUrl(successJson));
        resultJson.put("failUrl", failNormalOssUrl(failJson));
        return resultJson;
    }

    /**
     * 修改商家信息
     */
    public int updateProcessMch(MchInfoEntity mchInfo, PointDTO location) {
        MchInfoEntity upmchInfo = mchInfoMapper.selectById(mchInfo.getMchNo());
        if (mchInfo.getAddress() == null || mchInfo.getLocation() == null) {
            throw new ServiceException("信息修改失败,信息为空或不全");
        }
        upmchInfo.setAddress(mchInfo.getAddress());
        upmchInfo.setLocation(mchInfo.getLocation());
        upmchInfo.setOrderSort(mchInfo.getOrderSort());
        upmchInfo.setMchShortName(mchInfo.getMchShortName());
        upmchInfo.setMchBannerImage(mchInfo.getMchBannerImage());
        upmchInfo.setMchListImage(mchInfo.getMchListImage());
        int i = mchInfoMapper.updateProcessMch(upmchInfo, location);
        if (i > 0) {
            return i;
        }else {
            throw new ServiceException("信息修改失败");
        }
    }

    /**
     * 商家卡券下架
     */
    public Integer removeActivitiesMch(String activityId, String awardId) {
        Map map = activityMapper.selectActivitys(activityId);
        awardId = map.get("awardId").toString();

        ActivityEntity activity = activityMapper.selectById(Long.valueOf(activityId));
        if (activity == null) {
            throw new ServiceException("活动不存在");
        }
        activity.setState(6);
        int i = activityMapper.updateById(activity);
        AwardCouponEntity couponAwardEntity = awardCouponMapper.selectById(awardId);
        couponAwardEntity.setState(1);
        awardCouponMapper.updateById(couponAwardEntity);
        return i;
    }

    /**
     * 其余福分数据匹配（根据手机号匹配）
     *
     * @param ossFileUrl
     * @return
     */
    public JSONObject otherPoints(String ossFileUrl) {
        if (ObjectUtils.isEmpty(ObjectUtils.isEmpty(ossFileUrl))) {
            throw new BizException("请求参数异常");
        }
        JSONObject resultJson = new JSONObject();
        // 下载文件并记录oss
        File file = downloadFileAndSaveOssRecord(ossFileUrl, Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_IMPORT);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("手机号", "phone");
        reader.addHeaderAlias("福分值", "scoreValue");

        List<FansVO> read = reader.readAll(FansVO.class);
        if (ObjectUtils.isEmpty(read)) {
            throw new BizException("未查询到文件内容，请检查");
        }
        Set<String> phoneSet = read.stream().map(FansVO::getPhone).filter(ObjectUtils::isNotEmpty).collect(Collectors.toSet());
        if (ObjectUtils.isEmpty(phoneSet)) {
            throw new BizException("未查询到手机号，请检查");
        }

        // 筛选合计福分 >0 的数据
        read = read.stream().filter(item -> item.getScoreValue() > 0).collect(Collectors.toList());

        List<JSONObject> successJson = new ArrayList<>();
        List<JSONObject> failJson = new ArrayList<>();

        for (FansVO fansVo : read) {
            JSONObject successResult = new JSONObject();
            JSONObject failResult = new JSONObject();
            List<FansVO> fansList = fansAuthMapper.otherPoints(fansVo);
            // 失败信息记录
            failResult.put("phone", fansVo.getPhone());
            failResult.put("scoreValue", fansVo.getScoreValue());
            if (ObjectUtils.isEmpty(fansList)) {
                failResult.put("reason", "该手机号不存在实名信息");
                failJson.add(failResult);
                continue;
            }
            if (fansList.size() > 1) {
                failResult.put("reason", "该手机号存在多条实名信息");
                failJson.add(failResult);
                continue;
            }
            FansVO fans = fansList.get(0);
            if (fans.getIsFollow().equals(1)) {
                failResult.put("reason", "未关注公众号");
                failJson.add(failResult);
                continue;
            }
            // 成功信息记录
            if (ObjectUtils.isNotEmpty(fans.getOpenId()) && ObjectUtils.isNotEmpty(fans.getPhone())) {
                // 总福分
                Integer scoreValue = fansVo.getScoreValue();
                // 每条最大福分值一万
                int maxPoints = 10000;
                // 一万的次数
                int count = scoreValue / maxPoints;
                // 余数
                int residue = scoreValue % maxPoints;

                successResult.put("openid", fans.getOpenId());
                successResult.put("phone", fans.getPhone());
                successResult.put("scoreValue", maxPoints);
                successResult.put("overDays", "60");
                for (int i = 0; i < count; i++) {
                    successJson.add(new JSONObject(successResult));
                }
                successResult.put("scoreValue", residue);
                successJson.add(successResult);
            }
        }

        resultJson.put("successUrl", successNormalOssUrl(successJson));
        resultJson.put("failUrl", failOtherNormalOssUrl(failJson));
        return resultJson;
    }

    /**
     * 福分匹配成功的结果文件
     *
     * @param jsonObjects
     * @return
     */
    public String successNormalOssUrl(List<JSONObject> jsonObjects) {
        String successUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/normal/success/%s%s.xlsx", DateUtil.date().getTime(), "normal");
            File normalFile = new File(successFileName);
            ExcelWriter successWriter = ExcelUtil.getWriter(normalFile);
            successWriter.addHeaderAlias("openid", "小程序openid");
            successWriter.addHeaderAlias("phone", "手机号");
            successWriter.addHeaderAlias("scoreValue", "积分值");
            successWriter.addHeaderAlias("overDays", "过期天数");
            try {
                successWriter.write(jsonObjects);
                successWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                successUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType("yx");
                ossRecordEntity.setOssUrl(successUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_SUCCESS_NORMAL);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return successUrl;
    }

    /**
     * 绑卡消费福分匹配失败的结果文件
     *
     * @param jsonObjects
     * @return
     */
    public String failNormalOssUrl(List<JSONObject> jsonObjects) {
        String failUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/normal/fail/%s%s.xlsx", DateUtil.date().getTime(), "normal");
            File normalFile = new File(successFileName);
            ExcelWriter successWriter = ExcelUtil.getWriter(normalFile);
            successWriter.addHeaderAlias("ID", "ID");
            successWriter.addHeaderAlias("num", "绑卡消费次数");
            successWriter.addHeaderAlias("scoreValue", "福分值");
            successWriter.addHeaderAlias("reason", "失败原因");
            try {
                successWriter.write(jsonObjects);
                successWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType("yx");
                ossRecordEntity.setOssUrl(failUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_FAIL_NORMAL);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return failUrl;
    }

    /**
     * 其余福分匹配失败的结果文件
     *
     * @param jsonObjects
     * @return
     */
    public String failOtherNormalOssUrl(List<JSONObject> jsonObjects) {
        String failUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/normal/fail/%s%s.xlsx", DateUtil.date().getTime(), "normal");
            File normalFile = new File(successFileName);
            ExcelWriter successWriter = ExcelUtil.getWriter(normalFile);
            successWriter.addHeaderAlias("phone", "手机号");
            successWriter.addHeaderAlias("scoreValue", "合计福分");
            successWriter.addHeaderAlias("reason", "失败原因");
            try {
                successWriter.write(jsonObjects);
                successWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType("yx");
                ossRecordEntity.setOssUrl(failUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_FAIL_NORMAL);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return failUrl;
    }

    /**
     * 下载文件并上传记录oss记录表
     *
     * @param ossFileUrl
     * @param uploadType
     * @return
     */
    public File downloadFileAndSaveOssRecord(String ossFileUrl, Integer uploadType) {
        File file = cn.hutool.core.io.FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        HttpUtil.downloadFile(ossFileUrl, file);

        LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = new LambdaQueryWrapper<>();
        ossRecordWrapper.eq(OssRecordEntity::getOssUrl, ossFileUrl);
        ossRecordWrapper.eq(OssRecordEntity::getUploadType, uploadType);
        OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(ossRecordWrapper);
        if (null == recordEntity) {
            // 添加oos上传记录
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType("yx");
            ossRecordEntity.setOssUrl(ossFileUrl);
            ossRecordEntity.setFileSize(file.length());
            ossRecordEntity.setUploadType(uploadType);
            ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
            ossRecordEntity.setCreatedAt(new Date());
            ossRecordService.save(ossRecordEntity);
        }
        return file;
    }

    /**
     * 活动审批增加记录
     *
     * @param activityId
     */
    @Transactional
    public void addAuditRecords(Long activityId) {
        // 查询活动
        ActivityEntity activityEntity = activityMapper.selectById(activityId);
        log.info("新建活动信息：{}", JSONObject.toJSONString(activityEntity));
        SysUser sysUser = sysUserService.getById(activityEntity.getCreatedUid());
        log.info("系统用户信息：{}", JSONObject.toJSONString(sysUser));
        // 获取活动的审批流程
        AuAuditEntity auditEntity = auAuditService.getBaseMapper().selectByAuditType(Constants.AUDIT_TYPE.ACTIVITY);
        if (null == auditEntity) {
            throw new BizException("审批类型不存在");
        }
        // 运营创建的活动运营自己审核
        if (Constants.SYS_ROLE_TYPE.MANAGER.equals(sysUser.getSysType())) {
            AuAuditFlowEntity auditFlowEntity = auAuditFlowService.getBaseMapper().selectAuditFlowByAuditIdAndLevel(auditEntity.getAuditId(), 0);
            auAuditRecordsService.add(activityId, sysUser, auditFlowEntity, Constants.AUDIT_INFO_TYPE.MANAGE, null);
        } else if (Constants.SYS_ROLE_TYPE.PROXY.equals(sysUser.getSysType())) {
            // 机构创建的活动
            AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(sysUser.getBelongInfoId());
            log.info("系统用户所归属机构信息：{}", JSONObject.toJSONString(agentInfo));
            AuAuditFlowEntity auditFlowEntity = auAuditFlowService.getBaseMapper().selectAuditFlowByAuditIdAndLevel(auditEntity.getAuditId(), agentInfo.getLevel());
            // 查询活动挂载的小程序机构号
            List<ActivityVO> activityAgentNos = activityAppService.getActivityAgentNo(Constants.AGENT_APP_TYPE.WX_LITE, List.of(activityId));
            if (ObjectUtils.isEmpty(activityAgentNos)) {
                throw new BizException("未查询到活动挂载小程序机构号");
            }
            // 如果活动挂载的小程序机构号是本级的本级先审
            AuAuditRecordsEntity result = new AuAuditRecordsEntity();
            result.setActivityId(activityId);
            result.setAuditSerialNo("AUDIT"+ Utils.generateBathNo());
            result.setState(Constants.AUDIT_STATE.UN_AUDIT);
            result.setInfoType(Constants.AUDIT_INFO_TYPE.PROXY);
            if (agentInfo.getAgentNo().equals(activityAgentNos.get(0).getAgentNo())) {
                result.setAuditFlowId(auditFlowEntity.getAuditFlowId());
                result.setInfoId(agentInfo.getAgentNo());
            }else {
                // 不是本级直接让上级审
                int auditLevel = auditFlowEntity.getAuditLevel() - 1;
                AuAuditFlowEntity auditFlow = auAuditFlowService.getBaseMapper().selectAuditFlowByAuditIdAndLevel(auditEntity.getAuditId(), auditLevel);
                result.setAuditFlowId(auditFlow.getAuditFlowId());
                switch (auditLevel) {
                    case 0 -> {
                        result.setInfoId(null);
                        result.setInfoType(Constants.AUDIT_INFO_TYPE.MANAGE);
                    }
                    case 1 -> result.setInfoId(agentInfo.getAgentNo1());
                    case 2 -> result.setInfoId(agentInfo.getAgentNo2());
                    case 3 -> result.setInfoId(agentInfo.getAgentNo3());
                    default -> throw new BizException("审批级别异常");
                }
            }
            auAuditRecordsService.getBaseMapper().insert(result);
        }
    }


    /**
     * 查询派券活动数据
     *
     * @param templateNo
     * @param activityNo   活动编号
     * @param activityName 活动名称
     * @param startTime    开始时间
     * @param endTime      结束时间
     * @param userId
     * @return
     */
    public List<ActivityAndCouponVO> sendToMchUserActivityListV2(String templateNo, String activityNo, String activityName,
                                                                 String startTime, String endTime, Long userId, Long fansId, String appId) {
        if (StringUtils.isEmpty(templateNo)) {
            throw new BizException("网络故障，请稍后重试！");
        }
        // 参数校验
        if (ObjectUtils.isEmpty(userId)) {
            throw new BizException("参数异常");
        }

        // 查询用户绑定信息
        FansUserEntity fansUserEntity = fansUserService.getById(userId);
        if (fansUserEntity == null) {
            throw new BizException("未查询到用户信息");
        }
        FansAgentEntity fansAgentEntity = fansAgentService.getOne(FansAgentEntity.gw().eq(FansAgentEntity::getFansId, fansId).eq(FansAgentEntity::getAppId,appId).eq(FansAgentEntity::getIsDeleted, 0));
        if (fansAgentEntity == null) {
            throw new BizException("未绑定机构派券权限");
        }
        AgentEmployeeEntity agentEmployee = agentEmployeeService.getById(fansAgentEntity.getAgentEmployeeId());
        if (ObjectUtils.isEmpty(agentEmployee) || ObjectUtils.isEmpty(agentEmployee.getAgentNo())) {
            throw new BizException("未查询到机构员工");
        }

        // 查询机构信息
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(agentEmployee.getAgentNo());
        if (ObjectUtils.isEmpty(agentInfo)) {
            throw new BizException("机构状态异常");
        }
        //定义查询参数
        AwardAgentSearchParams searchParams = new AwardAgentSearchParams();
        searchParams.setAgentNo1(agentInfo.getAgentNo1()).setAgentNo2(agentInfo.getAgentNo2())
                .setAgentNo3(agentInfo.getAgentNo3()).setAgentNo4(agentInfo.getAgentNo4()).setLevel(agentInfo.getLevel())
                .setTemplateNo(templateNo).setActivityNo(activityNo).setActivityName(activityName)
                .setStartTime(startTime).setEndTime(endTime).setAppId(appId);
        // 查询活动及卡券信息
        List<ActivityAndCouponVO> activityAndCouponVOS = activityMapper.querySendToMchUserActivityList(searchParams);
        log.info("查询活动及卡券信息：{}", activityAndCouponVOS);

        //查询无限制的卡券信息
        List<ActivityAndCouponVO> activityAndNoLimitCouponVOList = activityMapper.querySendToMchUserNoLimitActivityList(searchParams);
        log.info("查询无限制的卡券信息：{}", activityAndNoLimitCouponVOList);

        activityAndCouponVOS.addAll(activityAndNoLimitCouponVOList);
        log.info("最终活动及卡券信息：{}", activityAndCouponVOS);
        return activityAndCouponVOS;
    }


    /**
     * 活动列表--lite
     */
    public List<ActivityListVO> queryListByLite(ActivityListDTO activityListDTO) {
        return this.baseMapper.queryList(activityListDTO);
    }

    /**
     * 活动详情--lite
     */
    public ActivityDetailVo detailByLite(Long activityId, Long fansId) {
        if (activityId == null) {
            throw new BizException("活动id不能为空");
        }
        FansUserEntity fansUser = fansUserService.selectUser(activityId, fansId);
        ActivityEntity activityEntity = getById(activityId);
        if (activityEntity == null) {
            throw new BizException("该活动不存在");
        }
        ActivityDetailVo activityDetailVo = new ActivityDetailVo();
        BeanUtils.copyProperties(activityEntity, activityDetailVo);
        Long payAuthId = activityEntity.getPayAuthId();
        if (payAuthId != null) {
            PayAuthEntity payAuthEntity = payAuthService.detailByLite(payAuthId);
            if (payAuthEntity == null) {
                throw new BizException("该活动出资方不存在");
            } else {
                LambdaQueryWrapper<FansPayEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(FansPayEntity::getFansId, fansId);
                queryWrapper.eq(FansPayEntity::getIfCode, payAuthEntity.getIfCode());
                FansPayEntity payAuth = fansPayService.getOne(queryWrapper);
                if (payAuth == null) {
                    JSONObject json = JSONObject.parseObject(payAuthEntity.getConfigVal());
                    activityDetailVo.setIfCode(payAuthEntity.getIfCode());
                    activityDetailVo.setAuthConfig(json.getString("url"));
                    activityDetailVo.setIsCommSubject(payAuthEntity.getIsCommSubject());
                }
            }
        }
//        ActivityTypeEntity typeEntity = activityTypeService.getActivityType(activityId);
//        if("reduce".equals(typeEntity.getActivityCode())){
//            List<ActivityAwardVO> list = activityAwardMapper.queryList(activityId);
//            log.info("立减活动卡券奖品：{}",JSONObject.toJSONString(list));
//            activityDetailVo.setCouponId(list.get(0).getAwardId());
//        }
        LambdaQueryWrapper<ActivitySettingEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivitySettingEntity::getActivityId, activityId);
        ActivitySettingEntity activitySettingEntity = activitySettingService.getOne(queryWrapper);
        if (null != activitySettingEntity) {
            activityDetailVo.setPeriodType(activitySettingEntity.getPeriodType());
            activityDetailVo.setSpecialType(activitySettingEntity.getSpecialType());
            activityDetailVo.setSpecialContent(activitySettingEntity.getSpecialContent());
            activityDetailVo.setTimeType(activitySettingEntity.getTimeType());
            activityDetailVo.setTimeStart(activitySettingEntity.getTimeStart());
            activityDetailVo.setTimeEnd(activitySettingEntity.getTimeEnd());
        }
        LambdaQueryWrapper<ActivityShareEntity> gw = ActivityShareEntity.gw();
        gw.eq(ActivityShareEntity::getActivityId, activityId);
        ActivityShareEntity activityShareEntity = activityShareService.getOne(gw);
        activityDetailVo.setActivityShareEntity(activityShareEntity);
        JSONObject jsonObject = JSONObject.parseObject(fansUser.getConfigVal());
        if (jsonObject != null) {
            String authUrl = jsonObject.getString("authUrl");
            if (authUrl != null && !authUrl.isEmpty()) {
                activityDetailVo.setOfficialAuthUrl(authUrl);
            }
        }
        activityDetailVo.setOfficialAppId(fansUser.getAppId());
        return activityDetailVo;
    }

    /**
     * 获取商圈的活动列表
     *
     * @param iPage
     * @param agentNo
     * @param groupNo
     * @return
     */
    public IPage<ActivityVO> getGroupActivityList(IPage iPage, String agentNo, String groupNo) {
        if (agentNo.isEmpty() || groupNo.isEmpty()) {
            throw new BizException("请求参数缺失！");
        }
        return activityMapper.getGroupActivityList(iPage, agentNo, groupNo);
    }

    /**
     * 获取活动详情（机构 收单小程序活动详情展示）
     *
     * @param activityId
     */
    public ActivityVO getActivityDetail(Long activityId) {
        if (activityId == null) {
            throw new BizException("请求参数缺失！");
        }
        return activityMapper.getActivityDetail(activityId);
    }

    /**
     * 超时未审核
     */
    public void timeout() {
        LambdaQueryWrapper<ActivityEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivityEntity::getState, 1);
        queryWrapper.eq(ActivityEntity::getActivityTemplateNo, "ACTE026");
        queryWrapper.le(ActivityEntity::getStartTime, DateUtil.date());
        List<ActivityEntity> activityEntities = activityMapper.selectList(queryWrapper);
        log.info("活动模版未ACTE026的活动有：{}", activityEntities);
        for (ActivityEntity activityEntity : activityEntities) {

            LambdaQueryWrapper<AuAuditRecordsEntity> wrapper = AuAuditRecordsEntity.gw();
            wrapper.eq(AuAuditRecordsEntity::getActivityId, activityEntity.getActivityId())
                    .eq(AuAuditRecordsEntity::getState, 0);
            AuAuditRecordsEntity one = auAuditRecordsService.getBaseMapper().selectOne(wrapper);
            AuAuditRecordsEntity auAuditRecordsEntity = new AuAuditRecordsEntity();
            auAuditRecordsEntity.setRemark("超出活动时间上级未审核，自动驳回");
            if (one.getAuditFlowId() == 4L) {
                one.setAuditTime(new Date());
                one.setInfoId("超时自动审核");
                one.setSysUserId(null);
                one.setRealName("超时");
                one.setState(2);
                one.setRemark("超时自动驳回");
                auAuditRecordsService.getBaseMapper().updateById(one);
                auAuditRecordsService.upMchCoupion(activityEntity.getActivityId(), 0, auAuditRecordsEntity);
            } else if (one.getAuditFlowId() == 5L) {
                one.setAuditTime(new Date());
                one.setInfoId("超时自动审核");
                one.setSysUserId(null);
                one.setRealName("超时");
                one.setState(2);
                one.setRemark("超时自动驳回");
                auAuditRecordsService.getBaseMapper().updateById(one);
                auAuditRecordsService.upMchCoupion(activityEntity.getActivityId(), 0, auAuditRecordsEntity);
            }

        }
    }

    /**
     * 根据不同渠道码查询对应的活动列表
     **/
    public List<ActivityEntity> selectActivityListByChannelType(String channelCode, Integer channelType) {
        List<ActivityEntity> activityEntities = new ArrayList<>();
        if (0 == channelType) {
            //机构人员渠道码活动
            channelCode = channelCode.split("-")[1];
            activityEntities = activityMapper.selectActivityListByEmployee(channelCode);
        } else if (1 == channelType) {
            //商户渠道码活动
            channelCode = channelCode.split("-")[1];
            activityEntities = activityMapper.selectActivityList(channelCode);
        } else if (2 == channelType) {
            //机构网点渠道码活动
            activityEntities = activityMapper.selectActivityListByAgent(channelCode);
        }
        return activityEntities;
    }


    /**
     * 根据appid查询活动列表
     **/
    public IPage<ActivityEntity> selectActivityListByAppid(IPage page, String appid) {
        return activityAppService.selectActivityListByAppid(page);
    }

    /**
     * 公众号素材
     *
     * @param agentNo
     * @param imgUrl
     * @return
     */
    public String uploadPicToGzh(String agentNo, String imgUrl) {
        log.info("上传公众号图片素材接口调用，【机构号：{}，图片路径：{}】", agentNo, imgUrl);

        AgentAppEntity agentAppEntity = agentAppService.getOne(
                AgentAppEntity.gw().eq(AgentAppEntity::getAgentNo, agentNo)
                        .eq(AgentAppEntity::getType, "0")
                        .eq(AgentAppEntity::getIsDefault, "1")
        );
        if (Objects.isNull(agentAppEntity)) {
            log.info("未查询到该机构所属公众号！机构号：{}", agentNo);
            throw new BizException("未查询到该机构所属公众号!");
        }
        log.info("公众号上传素材，公众号参数：{}", JSONObject.toJSONString(agentAppEntity));
        try {
            WxMpService wxMpService = officialMenuService.setWxService(agentAppEntity.getAppId());
            return officialService.uploadPicToGzh(agentAppEntity.getAppId(), imgUrl, FileUtil.convert(imgUrl), "image", wxMpService);
        } catch (Exception e) {
            throw new BizException("公众号上传素材失败！");
        }
    }

    /**
     * 商家卡券查询
     */
    public List<AwardCouponDTO> selectProcessMch(Long fansId, Integer state) {
        LambdaQueryWrapper<FansMchEntity> queryWrapper = FansMchEntity.gw();
        queryWrapper.eq(FansMchEntity::getFansId, fansId);
        queryWrapper.eq(FansMchEntity::getIsDeleted, 0);
        List<FansMchEntity> fansMchEntity = fansMchService.list(queryWrapper);
        List<AwardCouponDTO> maps = new ArrayList<>();
        if (fansMchEntity == null) {
            return maps;
        }
        for (FansMchEntity fansMchEntity1 : fansMchEntity) {
            MchInfoEntity mchInfo = mchInfoMapper.selectById(fansMchEntity1.getMchNo());
            String agentNo = mchInfo.getAgentNo();
            List<AwardCouponDTO> awardCouponDTOS = awardCouponMapper.selectProcessMchInFo(fansId, agentNo, state);
            for (AwardCouponDTO awardCouponDTO : awardCouponDTOS) {
                maps.add(awardCouponDTO);
            }
        }
        return maps;
    }

    /**
     * 根据奖品ID 获取活动信息
     *
     * @param awardId
     * @return
     */
    public ActivityVO findActivityNameByAwardId(Long awardId) {
        return baseMapper.findActivityNameByAwardId(awardId);
    }

    /**
     * 查询一次性派发积分结果文件
     *
     * @param type
     * @return
     */
    public List<OssRecordEntity> pointsResultFileUrl(String type) {
        if (ObjectUtils.isEmpty(ObjectUtils.isEmpty(type))) {
            throw new BizException("请求参数异常");
        }
        // 查询结果文件
        LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = OssRecordEntity.gw();
        ossRecordWrapper.eq(OssRecordEntity::getUploadType, type);
        List<OssRecordEntity> ossRecordList = ossRecordService.list(ossRecordWrapper);
        if (ossRecordList.isEmpty()) {
            throw new BizException("暂无结果文件");
        }
        // 按照创建时间倒叙
        ossRecordList.sort(Comparator.comparing(OssRecordEntity::getCreatedAt).reversed());
        return ossRecordList;
    }

    /**
     * 导出某个活动的报表
     *
     * @param activityId
     * @return
     */
    public ApiRes exportActivity(Long activityId, com.fjwt.gz.core.entity.SysUser sysUser) {
        if (null == activityId) {
            throw new BizException("请求参数缺失！");
        }
        ActivityEntity activityEntity = activityMapper.selectById(activityId);
        if (null == activityEntity) {
            throw new BizException("活动信息有误");
        }
        // 报表名称
        String fileName = activityEntity.getActivityNo() + activityEntity.getActivityName() + "基础数据报表";
        // 添加导出任务记录
        Long exportTaskId = sysExportTaskService.addExportTask(sysUser, fileName, activityEntity.getActivityTemplateNo(),
                Constants.EXPORT_TASK_ENUM.RESOURCE_TYPE.ACTIVITY,
                JSONObject.of("activityId", activityId, "agentNo", activityEntity.getAgentNo()).toJSONString());
        // 发送mq
        mqSender.send(ExportExcelMQ.build(exportTaskId));
        return ApiRes.ok();
    }

    /**
     * 商家活动审批增加记录
     *
     * @param activityId
     */
    @Transactional
    public void mchAddAuditRecords(Long activityId, Long fansId) {
        // 查询活动
        ActivityEntity activityEntity = activityMapper.selectById(activityId);
        log.info("新建活动信息：{}", JSONObject.toJSONString(activityEntity));

        SysUser sysUser = new SysUser();
        log.info("系统用户信息：{}", JSONObject.toJSONString(sysUser));

        sysUser.setSysUserId(activityEntity.getCreatedUid());

        // 获取活动的审批流程
        AuAuditEntity auditEntity = auAuditService.getBaseMapper().selectByAuditType(Constants.AUDIT_TYPE.MCHCOUPON);
        if (null == auditEntity) {
            throw new BizException("审批类型不存在");
        }
        AuAuditFlowEntity auditFlowEntity = auAuditFlowService.getBaseMapper().selectAuditFlowByAuditIdAndLevel(auditEntity.getAuditId(), 2);
        auAuditRecordsService.add(activityId, sysUser, auditFlowEntity, Constants.AUDIT_INFO_TYPE.FANS, null);
    }

    /**
     * 导入定向派券活动名单
     *
     * @return
     */
    public String assignImport(Long activityId, String ossFileUrl, String appId) {
        if (ObjectUtils.isEmpty(activityId) || StrUtil.isBlank(ossFileUrl) || StrUtil.isBlank(appId)) {
            throw new BizException("请求参数异常");
        }

        File file = downloadFileAndSaveOssRecord(ossFileUrl, Constants.OSS_UPLOAD_TYPE.ACTIVITY_ASSIGN_IMPORT);

        List<JSONObject> jsonObjects = new ArrayList<>();

        FansActivityDTO activityDTO = new FansActivityDTO();
        activityDTO.setActivityId(activityId);
        activityDTO.setAppId(appId);

        try (ExcelReader reader = ExcelUtil.getReader(file)) {
            List<Object> read = reader.readColumn(0, 1);
            if (CollUtil.isEmpty(read) || ObjectUtils.isEmpty(read.get(0))) {
                throw new BizException("未查询到文件内容，请检查");
            }

            List<String> phoneList = read.stream()
                    .filter(Objects::nonNull)
                    .map(Object::toString)
                    .collect(Collectors.toList());

            Map<String, Long> phoneFansIdMap = Collections.emptyMap();
            List<FansEntity> fansEntityList = fansService.list(FansEntity.gw().in(FansEntity::getPhone, phoneList));
            if (!fansEntityList.isEmpty()) {
                phoneFansIdMap = fansEntityList.stream()
                        .collect(Collectors.toMap(
                                FansEntity::getPhone,
                                FansEntity::getFansId,
                                (existing, replacement) -> existing
                        ));
            }

            BaseActivityService activityService = SpringBeansUtil.getBean("ACTE022Service", BaseActivityService.class);

            for (String phone : phoneList) {
                JSONObject result = new JSONObject();
                result.put("phone", phone);

                if (!phoneFansIdMap.containsKey(phone)) {
                    result.put("result", "用户不存在");
                    continue;
                }
                Long fansId = phoneFansIdMap.get(phone);
                activityDTO.setFansId(fansId);
                try {
                    activityService.takePartIn(activityDTO);
                    result.put("result", "发放成功");
                } catch (Exception e) {
                    if (e instanceof BizException) {
                        BizException bizException = (BizException) e;
                        String msg = bizException.getApiRes().getMsg();
                        Integer code = bizException.getApiRes().getCode();
                        if (code == 40002) {
                            msg = "用户未关注公众号";
                        }
                        result.put("result", msg);
                    } else {
                        log.error("{}用户产生异常：{}", phone, e.getMessage(), e);
                        result.put("result", "用户数据异常");
                    }
                }
                jsonObjects.add(result);
            }

        } finally {
            cn.hutool.core.io.FileUtil.del(file);
        }

        log.info("定向派券结果: {} ", jsonObjects);

        return toOssUrl(jsonObjects);
    }


    /**
     * 导入一次性派发积分活动
     *
     * @return
     */
    public String disposableImport(String ossFileUrl, String appId, Long sysUserId, String name, Long activityId) {
        String agentNo = "";
        if (ObjectUtils.isEmpty(activityId)) {
            AgentAppEntity agentAppEntity = agentAppService.getBaseMapper().selectOne(AgentAppEntity.gw().eq(AgentAppEntity::getAppId, appId));
            agentNo = agentAppEntity.getAgentNo();
            ActivityEntity activityEntity = new ActivityEntity();
            activityEntity.setAgentNo(agentAppEntity.getAgentNo());
            activityEntity.setAgentNo1(agentAppEntity.getAgentNo1());
            activityEntity.setAgentNo2(agentAppEntity.getAgentNo2());
            activityEntity.setAgentNo3(agentAppEntity.getAgentNo3());
            activityEntity.setAgentNo4(agentAppEntity.getAgentNo4());
            // 定义时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            // 获取当前时间并格式化
            String timestamp = LocalDateTime.now().format(formatter);
            activityEntity.setActivityNo("ACNO" + timestamp);
            activityEntity.setActivityTemplateNo("ACTE023");
            activityEntity.setActivityName(name);
            activityEntity.setStartTime(new Date());
            // 设置结束时间为1天后
            activityEntity.setEndTime(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000));
            activityEntity.setState(4);
            activityEntity.setRemark(name);
            activityEntity.setCreatedUid(sysUserId);
            this.save(activityEntity);
            activityId = activityEntity.getActivityId();
        }else {
            ActivityEntity activityEntity = this.getById(activityId);
            if (ObjectUtils.isEmpty(activityEntity)) {
                throw new BizException("活动异常，请检查");
            }
            name = activityEntity.getActivityName();
            agentNo = activityEntity.getAgentNo();
        }
        if (ObjectUtils.isEmpty(activityId) || StrUtil.isBlank(ossFileUrl) || StrUtil.isBlank(appId)) {
            throw new BizException("请求参数异常");
        }

        // 下载文件并记录oss
        File file = downloadFileAndSaveOssRecord(ossFileUrl, Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_IMPORT);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("小程序openid", "openId");
        reader.addHeaderAlias("手机号", "phone");
        reader.addHeaderAlias("积分值", "scoreValue");
        reader.addHeaderAlias("过期天数", "overDays");

        List<FansVO> read = reader.readAll(FansVO.class);
        if (ObjectUtils.isEmpty(read)) {
            throw new BizException("未查询到文件内容，请检查");
        }
        Set<String> openidSet = read.stream().map(FansVO::getOpenId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toSet());
        if (ObjectUtils.isEmpty(openidSet)) {
            throw new BizException("未查询到文件内容，请检查");
        }
        Integer number = read.size();

        List<JSONObject> jsonObjects = new ArrayList<>();

        BaseActivityService activityService = SpringBeansUtil.getBean("ACTE023Service", BaseActivityService.class);

        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        for (FansVO fansVo : read) {
            try {
                Long finalActivityId = activityId;
                String finalAgentNo = agentNo;
                jsonObjects.add(executorService.submit(() -> distributionOfPoints(fansVo, activityService, finalActivityId, appId, finalAgentNo, number, sysUserId)).get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        executorService.shutdown();

        reader.close();
        cn.hutool.core.io.FileUtil.del(file);
        log.info(name + "一次性派发积分结果：{}", JSONUtil.toJsonStr(jsonObjects));

        // 上传结果文件
        String jsonObjectsOssUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/%s%s.xlsx", DateUtil.date().getTime(), "success");
            File successFile = new File(successFileName);
            BigExcelWriter successWriter = ExcelUtil.getBigWriter(successFile);
            successWriter.addHeaderAlias("openid", "小程序openid");
            successWriter.addHeaderAlias("phone", "手机号");
            successWriter.addHeaderAlias("scoreValue", "积分值");
            successWriter.addHeaderAlias("overDays", "过期天数");
            successWriter.addHeaderAlias("result", "发放结果");
            try {
                successWriter.write(jsonObjects);
                successWriter.close();
//                jsonObjectsOssUrl = uploadToOss(successFile,"result");
                MultipartFile multipartFile = new MockMultipartFile(successFileName, successFile.length(), new FileInputStream(successFile));
                jsonObjectsOssUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.DOWNLOAD);
                ossRecordEntity.setOssUrl(jsonObjectsOssUrl);
                ossRecordEntity.setFileSize(successFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_DISPOSABLE_RESULT_EXPORT);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return jsonObjectsOssUrl;
    }


    public JSONObject distributionOfPoints(FansVO fansVo, BaseActivityService activityService, Long activityId, String appId, String agentNo, Integer total, Long sysUserId) {
        JSONObject result = new JSONObject();
        result.put("openid", fansVo.getOpenId());
        result.put("phone", fansVo.getPhone());
        result.put("scoreValue", fansVo.getScoreValue());
        result.put("overDays", fansVo.getOverDays());
        FansActivityDTO activityDTO = new FansActivityDTO();
        activityDTO.setActivityId(activityId);
        activityDTO.setExtJson(JSONUtil.toJsonStr(result));
        activityDTO.setAppId(appId);

        // 查询openid对应用户
        FansUserEntity fansUserEntity = fansUserService.getOne(FansUserEntity.gw()
                .eq(FansUserEntity::getOpenId, fansVo.getOpenId())
                .eq(FansUserEntity::getAppId, appId)
                .eq(FansUserEntity::getType, 1));

        if (ObjectUtils.isNotEmpty(fansUserEntity)) {
            //查询fansId对应手机号
            FansEntity fansEntity = fansService.getOne(FansEntity.gw()
                    .eq(FansEntity::getFansId, fansUserEntity.getFansId()));

            if (ObjectUtils.isNotEmpty(fansEntity)) {
                try {
                    activityDTO.setAppId(fansUserEntity.getAppId());
                    activityDTO.setFansId(fansEntity.getFansId());
                    activityDTO.setAgentNo(agentNo);
                    activityService.takePartIn(activityDTO);
//                    wsChannelServer.convertAndSend(String.valueOf(sysUserId), total,"openid: "+ fansVo.getOpenId()+"  积分派发","openid: "+ fansVo.getOpenId()+"  积分派发 "+" 发放成功", WebSocketConstants.ImportStatus.SUCCESS);
                    result.put("result", "发放成功");
                } catch (Exception e) {
                    if (e instanceof BizException) {
                        BizException bizException = (BizException) e;
                        result.put("result", bizException.getApiRes().getMsg());
                        Integer code = bizException.getApiRes().getCode();
                        if (code == 40002) {
//                            wsChannelServer.convertAndSend(String.valueOf(sysUserId), total, "openid: "+ fansVo.getOpenId()+"  积分派发","openid: "+ fansVo.getOpenId()+"  积分派发 "+" 用户未关注公众号", WebSocketConstants.ImportStatus.FAIL);
                            result.put("result", "用户未关注公众号");
                        }
                    } else {
                        log.info("openid:{}，phone:{} 用户产生异常：{}", fansVo.getOpenId(), fansVo.getPhone(), e.getMessage());
//                        wsChannelServer.convertAndSend(String.valueOf(sysUserId), total, "openid: "+ fansVo.getOpenId()+"  积分派发","openid: "+ fansVo.getOpenId()+"  积分派发 "+" 系统异常", WebSocketConstants.ImportStatus.FAIL);
                        result.put("result", "系统异常");
                        e.printStackTrace();
                    }
                }
            } else {
//                wsChannelServer.convertAndSend(String.valueOf(sysUserId), total, "openid: "+ fansVo.getOpenId()+"  积分派发","openid: "+ fansVo.getOpenId()+"  积分派发 "+" 未查询到会员", WebSocketConstants.ImportStatus.FAIL);
                result.put("result", "未查询到会员");
            }
        } else {
//            wsChannelServer.convertAndSend(String.valueOf(sysUserId), total, "openid: "+ fansVo.getOpenId()+"  积分派发","openid: "+ fansVo.getOpenId()+"  积分派发 "+" 未查询到用户", WebSocketConstants.ImportStatus.FAIL);
            result.put("result", "未查询到用户");
        }
        return result;
    }

    public String toOssUrl(List<JSONObject> jsonObjects) {
        String failUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/activity022023/fail/%s.xlsx", DateUtil.date().getTime());
            File normalFile = new File(successFileName);
            ExcelWriter failWriter = ExcelUtil.getWriter(normalFile);
            failWriter.addHeaderAlias("phone", "手机号");
            failWriter.addHeaderAlias("result", "派券结果");
            try {
                failWriter.write(jsonObjects);
                failWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.DOWNLOAD);
                ossRecordEntity.setOssUrl(failUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.MCH_INFO_COMPARE_FAIL);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return failUrl;
    }

    /**
     * C端消费者参与次数查询
     *
     * @param fansActivityDTO
     * @return
     */
    public int getFansAwardTimes(FansActivityDTO fansActivityDTO) {
        Long activityId = fansActivityDTO.getActivityId();
        String activityKey = String.format("%s%s:%s", Constants.REDIS_ACTIVITY.FILENAME, activityId, Constants.REDIS_ACTIVITY.BASE_INFO);
        ActivityEntity activityEntity = RedisUtil.getObject(activityKey, ActivityEntity.class);
        boolean isExistActivity = false;
        if (activityEntity == null) {
            activityEntity = getById(activityId);
            if (activityEntity == null) {
                throw new BizException("当前活动不存在");
            }
        } else {
            isExistActivity = true;
            log.info(String.format("活动主表在Redis中存在，ID: %s", activityId));
        }
        if (activityEntity.getState() != 4) {
            throw new BizException("当前活动未上线");
        }
        Long currentDate = System.currentTimeMillis();
        Date startDate = activityEntity.getStartTime();
        if (startDate.getTime() > currentDate) {
            throw new BizException("当前活动还未开始");
        }
        Date endDate = activityEntity.getEndTime();
        Long redisOutTime = endDate.getTime() - DateUtil.date().getTime();
        if (endDate != null && endDate.getTime() < currentDate) {
            throw new BizException("当前活动已结束");
        }
        if (!isExistActivity) {
            RedisUtil.set(activityKey, activityEntity);
            log.info(String.format("活动主表存入Redis中，ID: %s", activityId));
        }
        if (!isExistActivity) {
            RedisUtil.expire(activityKey, redisOutTime, TimeUnit.MILLISECONDS);
            log.info(String.format("活动相关表在Redis中过期时间为:%s，ID: %s", endDate, activityId));
        }

        ActivitySettingEntity activitySettingEntity = activitySettingService.getActivitySettingEntity(activityId, redisOutTime);

        String currentTimesKey = String.format("%s%s:%s%s", Constants.REDIS_ACTIVITY.FILENAME, activityEntity.getActivityId(), Constants.REDIS_ACTIVITY.USER_FILENAME, fansActivityDTO.getFansId());//用户参会活动次数redis缓存key
        log.info("每人参与的总次数redisKey:{}", currentTimesKey);
        ActivityUserTimesBO activityUserTimesBO = RedisUtil.getObject(currentTimesKey, ActivityUserTimesBO.class);//用户参会活动次数redis缓存
        log.info("每人参与的总次数redisValue:{}", JSONUtil.toJsonStr(activityUserTimesBO));

        if (activitySettingEntity.getPeriodType() > 0) {
            final int periodTimes = activitySettingEntity.getPeriodTimes();
            int currentPeriod = PeriodUtil.getPeriod(activitySettingEntity.getPeriodType());
            if (activityUserTimesBO != null) {
                int currentPeriodTimes = activityUserTimesBO.getCurrentPeriodTimes();
                int historyPeriod = activityUserTimesBO.getCurrentPeriod();
                if (currentPeriod == historyPeriod) {
                    if (currentPeriodTimes >= periodTimes) {
                        return 0;
                    } else {
                        return periodTimes - currentPeriodTimes;
                    }
                } else {
                    return periodTimes;
                }
            } else {
                return periodTimes;
            }
        }
        if (ObjectUtils.isEmpty(activityUserTimesBO)) {
            return activitySettingEntity.getOnlyOneTimes();
        }
        return activitySettingEntity.getOnlyOneTimes() - activityUserTimesBO.getTotalJoinTimes();
    }

    /**
     * 查询活动卡券三方回参是否填写
     */
    public void checkActivityCouponThirdParam(Long activityId) {
        List<ActivityAwardEntity> activityCouponList = activityAwardService.list(ActivityAwardEntity.gw().eq(ActivityAwardEntity::getActivityId, activityId));
        if (ObjectUtils.isNotEmpty(activityCouponList)) {
            List<Long> couponIds = activityCouponList.stream().filter(item -> Constants.AWARD.COUPON == item.getAwardType()).map(ActivityAwardEntity::getAwardId).toList();
            if (ObjectUtils.isNotEmpty(couponIds)) {
                checkCouponThirdParam(couponIds);
            }
        }
    }

    /**
     * 查询卡券三方回参是否填写
     */
    public void checkCouponThirdParam(List<Long> couponIds) {
        List<AwardCouponEntity> awardCouponList = awardCouponService.listByIds(couponIds);
        if (ObjectUtils.isEmpty(awardCouponList)) {
            throw new BizException("卡券配置异常，请检查！");
        }
        for (AwardCouponEntity awardCouponEntity : awardCouponList) {
            checkCouponThirdParam(awardCouponEntity);
        }
    }

    /**
     * 查询卡券三方回参是否填写
     */
    public void checkCouponThirdParam(AwardCouponEntity awardCouponEntity) {
        if (ObjectUtils.isEmpty(awardCouponEntity.getPayConfig())) {
            throw new BizException("请填写卡券回执");
        }
    }

    /**
     * 获取当前活动-已结束活动
     *
     * @param iPage
     * @param flag
     * @param appId
     * @return
     */
    public IPage<ActivityVO> getActivityList(IPage iPage, String flag, Long fansId, String appId) {
        if (ObjectUtils.isEmpty(fansId)) {
            throw new BizException("参数异常");
        }
        // 查询客户经理所绑定机构
        AgentEmployeeVO fansAgent = fansAgentService.getFansAgent(fansId, appId);
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(fansAgent.getAgentNo());
        if (ObjectUtils.isEmpty(agentInfo)) {
            throw new BizException("机构状态异常");
        }
        //查询权限为当前机构及下级的活动
        List<String> allSubAgentNo = agentInfoService.queryAllSubAgentNo(agentInfo.getAgentNo());

        return activityMapper.getActivityList(iPage, allSubAgentNo, flag);
    }

    /**
     * 查询小程序用户绑定商户后，该商户的所有活动列表,通过商户号查询
     **/
    public IPage<ActivityEntity> fansGetActivityByMchNo(IPage iPage,String mchNo, Integer state) {
        return activityMapper.fansGetActivityByMchNo(iPage,mchNo, state);
    }

    public List<ActivityAwardEntity> activityAwardList(Long activityId) {
        ActivityEntity activity = baseMapper.selectById(activityId);
        List<ActivityAwardEntity> list = activityAwardService.lambdaQuery().eq(ActivityAwardEntity::getActivityId, activityId).list();
        for (ActivityAwardEntity activityAwardEntity : list){
            if (activityAwardEntity.getAwardType() != 3){
                AwardSettingEntity awardSettingEntity = awardSettingService.lambdaQuery().eq(AwardSettingEntity::getAwardId, activityAwardEntity.getAwardId()).eq(AwardSettingEntity::getAwardType, activityAwardEntity.getAwardType()).one();
                if (awardSettingEntity == null){
                    throw new BizException("奖品配置异常");
                }
                activityAwardEntity.setIsNeedActivate(awardSettingEntity.getIsNeedActivate());
            }else {
                activityAwardEntity.setIsNeedActivate(0);
            }
            activityAwardEntity.setThumbMediaId(activity.getThumbMediaId());
        }
        return list;
    }


    public IPage<ExportAwardVO> activityAwardDetail(IPage iPage, ActivityAwardDTO activityAwardDTO) {
        ActivityEntity activity = baseMapper.selectById(activityAwardDTO.getActivityId());
        activityAwardDTO.setAgentNo(activity.getAgentNo());
        if (activityAwardDTO.getAwardType() == 0L){
            IPage<ExportAwardVO> exportAwardVOIPage = awardCouponService.activityCouponDetail(iPage, activityAwardDTO);
            extracted(exportAwardVOIPage.getRecords());
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 1L){
            IPage<ExportAwardVO> exportAwardVOIPage = awardGoodsService.activityGoodsDetail(iPage, activityAwardDTO);
            extracted(exportAwardVOIPage.getRecords());
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 2L){
            IPage<ExportAwardVO> exportAwardVOIPage = awardVirtualService.activityVirtualDetail(iPage, activityAwardDTO);
            extracted(exportAwardVOIPage.getRecords());
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 3L){
            IPage<ExportAwardVO> exportAwardVOIPage = awardScoreService.activityScoreDetail(iPage, activityAwardDTO);
            extracted(exportAwardVOIPage.getRecords());
            return exportAwardVOIPage;
        }
        throw new BizException("网络波动,请联系管理员");
    }

    private static void extracted(List<ExportAwardVO> exportAwardVOIPage) {
        for (ExportAwardVO exportAwardVO : exportAwardVOIPage){
            if (exportAwardVO.getChannelType() != null && !exportAwardVO.getChannelType().isEmpty()){
                if (!exportAwardVO.getChannelType().equals("机构渠道")){
                    String[] parts = exportAwardVO.getChannelCode().split("-");
                    if (parts.length >= 2) {
                        String part1 = parts[0];
                        String part2 = parts[1];
                        exportAwardVO.setChannelAgentNo(part1);
                        exportAwardVO.setChannelCode(part2);
                    } else {
                        throw new BizException("网络波动,请联系管理员");
                    }
                }else {
                    exportAwardVO.setChannelAgentNo(exportAwardVO.getChannelCode());
                    exportAwardVO.setChannelCode(null);
                }
            }
        }
    }
//暂时不用
//    // 添加获取总数的方法
//    public int countActivityAwardDetail(ActivityAwardDTO activityAwardDTO) {
//        if (activityAwardDTO.getAwardType() == 0L){
//            ExportAwardVO exportAwardVOIPage = awardCouponService.activityCouponNum(activityAwardDTO);
//            return exportAwardVOIPage.getNum();
//        }else {
//            throw new BizException("网络波动,请联系管理员");
//        }
//    }

    public List<ExportAwardVO> activityAwardDetail(ActivityAwardDTO activityAwardDTO) {
        ActivityEntity activity = baseMapper.selectById(activityAwardDTO.getActivityId());
        activityAwardDTO.setAgentNo(activity.getAgentNo());
        if (activityAwardDTO.getAwardType() == 0L){
            List<ExportAwardVO> exportAwardVOIPage = awardCouponService.activityCouponDetail(activityAwardDTO);
            for (ExportAwardVO exportAwardVO : exportAwardVOIPage){
                AgentInfoVO agentInfos = agentInfoService.getAgentInfos(exportAwardVO.getManagerAgentNo());
                if (agentInfos != null){
                    exportAwardVO.setManagerAgentNoName(agentInfos.getAgentName());
                    if (agentInfos.getLevel() != 1){
                        AgentInfoVO agentInfoVO = agentInfoService.getAgentInfos(agentInfos.getPid());
                        if (agentInfoVO != null){
                            exportAwardVO.setTallerManagerAgentNo(agentInfoVO.getAgentName());
                            exportAwardVO.setTallerManagerAgentNoName(agentInfoVO.getAgentName());
                        }
                    }
                }
            }
            extracted(exportAwardVOIPage);
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 1L){
            List<ExportAwardVO> exportAwardVOIPage = awardGoodsService.activityGoodsDetail(activityAwardDTO);
            extracted(exportAwardVOIPage);
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 2L){
            List<ExportAwardVO> exportAwardVOIPage = awardVirtualService.activityVirtualDetail(activityAwardDTO);
            extracted(exportAwardVOIPage);
            return exportAwardVOIPage;
        } else if (activityAwardDTO.getAwardType() == 3L){
            List<ExportAwardVO> exportAwardVOIPage = awardScoreService.activityScoreDetail(activityAwardDTO);
            extracted(exportAwardVOIPage);
            return exportAwardVOIPage;
        }
        throw new BizException("网络波动,请联系管理员");
    }

    /**
     * 导出看板报表
     *
     * @param
     * @return
     */
    public ApiRes exportReal(ActivityAwardDTO activityAwardDTO, com.fjwt.gz.core.entity.SysUser sysUser) {

        List<ActivityAwardEntity> activityAwardList = activityAwardService.list(ActivityAwardEntity.gw().eq(ActivityAwardEntity::getAwardId, activityAwardDTO.getAwardId()));
        if (null == activityAwardList) {
            throw new BizException("数据为空");
        }
        // 报表名称
        String fileName = activityAwardDTO.getAwardName() + "活动看板数据报表";
        // 添加导出任务记录
        Long exportTaskId = sysExportTaskService.addExportTask(sysUser, fileName, Constants.EXPORT_TASK_ENUM.REQUEST_CODE.ACTIVITY_BOARD,
                Constants.EXPORT_TASK_ENUM.RESOURCE_TYPE.ACTIVITY, JSONObject.toJSONString(activityAwardDTO));
        // 发送mq
//        mqSender.send(ExportExcelMQ.build(exportTaskId));
        return ApiRes.ok();
    }


    /**
     * acte017 报表导出
     * @param awardId
     * @param awardType
     * @param activityId
     */
    public void exportActivityInfo(String awardId, String awardType, String activityId) {

        if(StringUtils.isBlank(awardId) || StringUtils.isBlank(awardType) || StringUtils.isBlank(activityId)){
            throw new BizException("请求参数缺失！");
        }
        ActivityEntity activityEntity = activityMapper.selectById(activityId);
        if (null == activityEntity) {
            throw new BizException("活动信息有误");
        }

        // 添加导出任务记录  GzUserDetails.getCurrentUserDetails().getSysUser()
        SysUser sysUser = new SysUser();
        sysUser.setRealname("ceshi");
        sysUser.setSysType(Constants.SYS_ROLE_TYPE.MANAGER);
        sysUser.setBelongInfoId("11111");
        sysUser.setSysUserId(20351l);
        Long exportTaskId = sysExportTaskService.addExportTask(sysUser, getFileName(awardType), activityEntity.getActivityTemplateNo(),
                Constants.EXPORT_TASK_ENUM.RESOURCE_TYPE.ACTIVITY, JSONObject.of("activityId", activityId, "awardType", awardType, "awardId", awardId).toJSONString());
        // 发送mq
        mqSender.send(ExportExcelMQ.build(exportTaskId));
    }

    /**
     * 获取导出文件名称
     *
     * @param awardType
     * @return
     */
    private String getFileName(String awardType) {
        return switch (Integer.parseInt(awardType)) {
            case Constants.AWARD.COUPON, Constants.AWARD.GOODS ->
                    awardType + "_" + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
            case Constants.AWARD.SCORE -> "B2" + "_" + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
            default -> "";
        };
    }

    /**外部系统查询活动详情，通过活动ID、entryway、机构号**/
    public ActivityEntity getActivityToOutById(Long activityId,Long entryWay,String agentNoDb) {
        return activityAppService.getActivityToOutById(activityId,entryWay,agentNoDb);
    }

}
